package org.asiainfo.system.service.impl;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.util.SqlUtil;
import org.asiainfo.common.core.constant.TenantConstants;
import org.asiainfo.common.core.constant.UserConstants;
import org.asiainfo.common.core.exception.ServiceException;
import org.asiainfo.common.core.utils.StreamUtils;
import org.asiainfo.common.core.utils.StringUtils;
import org.asiainfo.common.mybatis.stream.core.page.TableDataInfo;
import org.asiainfo.common.mybatis.stream.core.page.PageQuery;
import org.asiainfo.common.mybatis.stream.utils.DataScopeUtils;
import org.asiainfo.common.satoken.utils.LoginHelper;
import org.asiainfo.system.api.model.LoginUser;
import org.asiainfo.system.domain.*;
import org.asiainfo.system.domain.bo.SysUserBo;
import org.asiainfo.system.domain.bo.SysUserRoleBo;
import org.asiainfo.system.domain.table.SysDeptTableDef;
import org.asiainfo.system.domain.table.SysRoleTableDef;
import org.asiainfo.system.domain.table.SysUserRoleTableDef;
import org.asiainfo.system.domain.table.SysUserTableDef;
import org.asiainfo.system.domain.vo.SysRoleVo;
import org.asiainfo.system.domain.bo.SysRoleBo;
import org.asiainfo.system.domain.vo.SysUserVo;
import org.asiainfo.system.mapper.*;
import org.asiainfo.system.service.SysRoleService;
import org.springframework.stereotype.Service;
import org.asiainfo.common.core.utils.MapstructUtils;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.mybatisflex.core.paginate.Page;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.mybatisflex.core.query.QueryMethods.bracket;
import static org.asiainfo.system.domain.table.SysRoleTableDef.SYS_ROLE;

/**
 * 角色信息表(SysRole)表服务实现类
 *
 * @author dotor-ww
 * @since 2024-01-15 21:17:26
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    private final SysRoleMenuMapper sysRoleMenuMapper;

    private final SysRoleDeptMapper sysRoleDeptMapper;

    private final SysUserMapper sysUserMapper;

    private final SysUserRoleMapper sysUserRoleMapper;

    /**
     * 构建查询条件
     *
     * @param sysRoleBo 筛选条件
     * @return 构建结果
     */
    private QueryWrapper builderQueryWrapper(SysRoleBo sysRoleBo) {
        Map<String, Object> params = sysRoleBo.getParams();
        QueryWrapper query = query();
        query.eq(SysRole::getRoleId, sysRoleBo.getRoleId(), ObjectUtil.isNotNull(sysRoleBo.getRoleId()));
        query.eq(SysRole::getRoleStatus, sysRoleBo.getRoleStatus(), ObjectUtil.isNotNull(sysRoleBo.getRoleStatus()));
        query.like(SysRole::getRoleName, sysRoleBo.getRoleName(), StringUtils.isNotBlank(sysRoleBo.getRoleName()));
        query.like(SysRole::getRoleKey, sysRoleBo.getRoleKey(), StringUtils.isNotBlank(sysRoleBo.getRoleKey()));
        query.between(SysRole::getCreateTime, params.get("beginTime"), params.get("endTime"),
            ObjectUtil.isNotNull(params.get("beginTime")) && ObjectUtil.isNotNull(params.get("endTime")));
        return query;
    }

    /**
     * 查询
     *
     * @param sysRoleBo 筛选条件
     * @return 查询结果
     */
    @Override
    public List<SysRoleVo> queryList(SysRoleBo sysRoleBo) {
        QueryWrapper query = builderQueryWrapper(sysRoleBo);
        return listAs(query, SysRoleVo.class);
    }

    /**
     * 通过roleId查询单条数据
     *
     * @param roleId 主键
     * @return 实例对象
     */
    @Override
    public SysRoleVo queryById(Long roleId) {
        QueryWrapper query = DataScopeUtils.addCondition(query());
        query.eq(SysRole::getRoleId, roleId);
        return getOneAs(query, SysRoleVo.class);
    }

    /**
     * 分页查询
     *
     * @param sysRoleBo 筛选条件
     * @param pageQuery 分页对象
     * @return 查询结果
     */
    @Override
    public TableDataInfo<SysRoleVo> queryPageList(SysRoleBo sysRoleBo, PageQuery pageQuery) {
        QueryWrapper query = DataScopeUtils.addCondition(builderQueryWrapper(sysRoleBo));
        pageQuery.buildOrder(query);
        if (StringUtils.isBlank(pageQuery.getOrderBy())) {
            query.orderBy(SysRole::getCreateTime).asc().orderBy(SysRole::getRoleSort);
        }
        Page<SysRoleVo> page = pageAs(pageQuery.buildPage(), query, SysRoleVo.class);
        return TableDataInfo.build(page);
    }

    /**
     * 新增数据
     *
     * @param sysRoleBo 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(SysRoleBo sysRoleBo) {
        SysRole sysRole = MapstructUtils.convert(sysRoleBo, SysRole.class);
        if (ObjectUtil.isNull(sysRole)) {
            throw new ServiceException("解析角色信息失败");
        }
        boolean save = save(sysRole);
        sysRoleBo.setRoleId(sysRole.getRoleId());
        insertRoleMenu(sysRoleBo);
        return save;
    }

    /**
     * 新增角色菜单信息
     *
     * @param sysRoleBo 角色对象
     */
    private void insertRoleMenu(SysRoleBo sysRoleBo) {
        List<SysRoleMenu> sysRoleMenus = new ArrayList<>();
        Long roleId = sysRoleBo.getRoleId();
        for (Long menuId : sysRoleBo.getMenuIds()) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu(roleId, menuId);
            sysRoleMenus.add(sysRoleMenu);
        }
        if (sysRoleMenus.size() > 0) {
            sysRoleMenuMapper.insertBatch(sysRoleMenus);
        }
    }


    /**
     * 修改数据
     *
     * @param sysRoleBo 实例对象
     * @return 实例对象
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(SysRoleBo sysRoleBo) {
        SysRole sysRole = MapstructUtils.convert(sysRoleBo, SysRole.class);
        if (ObjectUtil.isNull(sysRole)) {
            throw new ServiceException("更新角色失败,未获取到角色信息");
        }
        // 删除角色与菜单关联
        sysRoleMenuMapper.deleteByQuery(query().eq(SysRoleMenu::getRoleId, sysRole.getRoleId()));
        // 新增角色与菜单关联
        insertRoleMenu(sysRoleBo);
        // 修改角色信息
        return updateById(sysRole);
    }

    /**
     * 通过主键删除数据
     *
     * @param roleIds 主键
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> roleIds) {
        for (Long roleId : roleIds) {
            SysRole sysRole = getById(roleId);
            checkRoleAllowed(BeanUtil.toBean(sysRole, SysRoleBo.class));
            checkRoleDataScope(roleId);
            if (countUserRoleByRoleId(roleId) > 0) {
                throw new ServiceException("角色存在用户关联，不允许删除");
            }
        }
        List<Long> ids = roleIds.stream().toList();
        // 删除角色与菜单关联
        sysRoleMenuMapper.deleteByQuery(query().in(SysRoleMenu::getRoleId, ids));
        // 删除角色与部门关联
        sysRoleDeptMapper.deleteByQuery(query().in(SysRoleDept::getRoleId, ids));
        return removeByIds(roleIds);
    }

    /**
     * 校验角色数据权限
     *
     * @param roleId 角色ID
     */
    @Override
    public void checkRoleDataScope(Long roleId) {
        if (ObjectUtil.isNull(roleId)) {
            return;
        }
        if (LoginHelper.isSuperAdmin()) {
            return;
        }
        List<SysRoleVo> sysRoleVos = listAs(DataScopeUtils.addCondition(query().eq(SysRole::getRoleId, roleId)), SysRoleVo.class);
        if (CollUtil.isEmpty(sysRoleVos)) {
            throw new ServiceException("没有全访问角色数据");
        }
    }

    /**
     * 校验角色是否允许操作
     *
     * @param sysRoleBo 角色信息
     */
    @Override
    public void checkRoleAllowed(SysRoleBo sysRoleBo) {
        if (ObjectUtil.isNotNull(sysRoleBo.getRoleId()) && LoginHelper.isSuperAdmin(sysRoleBo.getRoleId())) {
            throw new ServiceException("不允许操作超级管理员角色");
        }
        String[] keys = new String[]{TenantConstants.TENANT_ADMIN_ROLE_KEY, TenantConstants.SUPER_ADMIN_ROLE_KEY};
        // 新增不允许使用 管理员标识符
        if (ObjectUtil.isNull(sysRoleBo.getRoleId()) && StringUtils.equalsAny(sysRoleBo.getRoleKey(), keys)) {
            throw new ServiceException("不允许使用系统内置管理员角色标识符");
        }
        // 修改不允许使用 管理员标识符
        if (ObjectUtil.isNotNull(sysRoleBo.getRoleId())) {
            SysRole sysRole = getById(sysRoleBo.getRoleId());
            if (StringUtils.equalsAny(sysRole.getRoleKey(), keys)) {
                throw new ServiceException("不允许修改系统内置管理员角色标识符");
            } else if (StringUtils.equalsAny(sysRoleBo.getRoleKey(), keys)) {
                throw new ServiceException("不允许使用系统内置管理员角色标识符");
            }
        }
    }

    /**
     * 校验角色名称是否唯一
     *
     * @param sysRoleBo 角色信息
     * @return 校验结果
     */
    @Override
    public Boolean checkRoleNameUnique(SysRoleBo sysRoleBo) {
        return exists(query()
            .eq(SysRole::getRoleName, sysRoleBo.getRoleName(), StringUtils.isNotBlank(sysRoleBo.getRoleName()))
            .ne(SysRole::getRoleId, sysRoleBo.getRoleId(), ObjectUtil.isNotNull(sysRoleBo.getRoleId())));
    }

    /**
     * 校验角色权限是否唯一
     *
     * @param sysRoleBo 角色信息
     * @return 校验结果
     */
    @Override
    public Boolean checkRoleKeyUnique(SysRoleBo sysRoleBo) {
        return exists(query()
            .eq(SysRole::getRoleKey, sysRoleBo.getRoleKey(), StringUtils.isNotBlank(sysRoleBo.getRoleKey()))
            .ne(SysRole::getRoleId, sysRoleBo.getRoleId(), ObjectUtil.isNotNull(sysRoleBo.getRoleId())));
    }

    /**
     * 角色状态更新
     *
     * @param sysRoleBo 角色信息
     * @return 更新结果
     */
    @Override
    public Boolean updateRoleStatusByRoleId(SysRoleBo sysRoleBo) {
        String roleStatus = sysRoleBo.getRoleStatus();
        Long roleId = sysRoleBo.getRoleId();
        if (UserConstants.ROLE_DISABLE.equals(roleStatus) && countUserRoleByRoleId(roleId) > 0) {
            throw new ServiceException("角色已分配,不能禁用");
        }
        return updateChain()
            .set(SysRole::getRoleStatus, roleStatus)
            .eq(SysRole::getRoleId, roleId)
            .update();
    }

    /**
     * 查询角色使用数量
     *
     * @param roleId 角色ID
     * @return 查询结果
     */
    @Override
    public Long countUserRoleByRoleId(Long roleId) {
        return count(query().from(SysUserRole.class).eq(SysUserRole::getRoleId, roleId));
    }

    /**
     * 获取角色选择框列表
     *
     * @return 下拉结果
     */
    @Override
    public List<SysRoleVo> optionSelect() {
        return listAs(query(), SysRoleVo.class);
    }

    /**
     * 查询已分配的角色列表
     *
     * @param sysUserBo 用户信息
     * @param pageQuery 分页信息
     * @return 查询结果
     */
    @Override
    public TableDataInfo<SysUserVo> selectAllocatedList(SysUserBo sysUserBo, PageQuery pageQuery) {
        QueryWrapper query = query().select(QueryMethods.distinct(
                SysUserTableDef.SYS_USER.USER_ID,
                SysUserTableDef.SYS_USER.DEPT_ID,
                SysUserTableDef.SYS_USER.USER_NAME,
                SysUserTableDef.SYS_USER.NICK_NAME,
                SysUserTableDef.SYS_USER.EMAIL,
                SysUserTableDef.SYS_USER.PHONE_NUMBER,
                SysUserTableDef.SYS_USER.USER_STATUS,
                SysUserTableDef.SYS_USER.CREATE_TIME
            ))
            .from(SysUser.class)
            .leftJoin(SysDept.class)
            .on(SysDeptTableDef.SYS_DEPT.DEPT_ID.eq(SysUserTableDef.SYS_USER.DEPT_ID))
            .leftJoin(SysUserRole.class)
            .on(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID.eq(SysUserTableDef.SYS_USER.USER_ID))
            .leftJoin(SysRole.class)
            .on(SYS_ROLE.ROLE_ID.eq(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID));

        query.eq(SysRole::getRoleId, sysUserBo.getRoleId(), ObjectUtil.isNotNull(sysUserBo.getRoleId()));
        query.like(SysUser::getUserName, sysUserBo.getUserName(), StringUtils.isNotBlank(sysUserBo.getUserName()));
        query.eq(SysUser::getUserStatus, sysUserBo.getUserStatus(), StringUtils.isNotBlank(sysUserBo.getUserStatus()));
        query.like(SysUser::getPhoneNumber, sysUserBo.getPhoneNumber(), StringUtils.isNotBlank(sysUserBo.getPhoneNumber()));
        String orderInfo = pageQuery.getOrderBy();
        query.orderBy(orderInfo);
        if (StringUtils.isBlank(orderInfo)) {
            query.orderBy(SysUser::getUserId);
        }
        // 添加数据权限
        DataScopeUtils.addCondition(query);
        Page<SysUserVo> page = sysUserMapper.paginateAs(pageQuery.buildPage(), query, SysUserVo.class);
        return TableDataInfo.build(page);
    }

    /**
     * 查询未分配的角色列表
     *
     * @param sysUserBo 用户信息
     * @param pageQuery 分页信息
     * @return 查询结果
     */
    @Override
    public TableDataInfo<SysUserVo> selectUnAllocatedList(SysUserBo sysUserBo, PageQuery pageQuery) {
        List<Long> userIds = queryChain()
            .select(SysUserTableDef.SYS_USER.USER_ID)
            .from(SysUser.class)
            .innerJoin(SysUserRole.class)
            .on(SysUserTableDef.SYS_USER.USER_ID.eq(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID))
            .and(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID.eq(sysUserBo.getRoleId()))
            .listAs(Long.class);

        QueryWrapper query = query().select(QueryMethods.distinct(
                SysUserTableDef.SYS_USER.USER_ID,
                SysUserTableDef.SYS_USER.DEPT_ID,
                SysUserTableDef.SYS_USER.USER_NAME,
                SysUserTableDef.SYS_USER.NICK_NAME,
                SysUserTableDef.SYS_USER.EMAIL,
                SysUserTableDef.SYS_USER.PHONE_NUMBER,
                SysUserTableDef.SYS_USER.USER_STATUS,
                SysUserTableDef.SYS_USER.CREATE_TIME
            ))
            .from(SysUser.class)
            .leftJoin(SysDept.class)
            .on(SysDeptTableDef.SYS_DEPT.DEPT_ID.eq(SysUserTableDef.SYS_USER.DEPT_ID))
            .leftJoin(SysUserRole.class)
            .on(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID.eq(SysUserTableDef.SYS_USER.USER_ID))
            .leftJoin(SysRole.class)
            .on(SYS_ROLE.ROLE_ID.eq(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID));

        query.and(bracket(SysRoleTableDef.SYS_ROLE.ROLE_ID.ne(sysUserBo.getRoleId()).or(SysRoleTableDef.SYS_ROLE.ROLE_ID.isNull())))
            .notIn(SysUser::getUserId, userIds, CollUtil.isNotEmpty(userIds))
            .like(SysUser::getUserName, sysUserBo.getUserName(), StringUtils.isNotBlank(sysUserBo.getUserName()))
            .like(SysUser::getPhoneNumber, sysUserBo.getPhoneNumber(), StringUtils.isNotBlank(sysUserBo.getPhoneNumber()));
        String orderInfo = pageQuery.getOrderBy();
        query.orderBy(orderInfo);
        if (StringUtils.isBlank(orderInfo)) {
            query.orderBy(SysUser::getUserId);
        }
        DataScopeUtils.addCondition(query);
        List<SysUserVo> sysUserVos = listAs(query, SysUserVo.class);
        return TableDataInfo.build(sysUserVos);
    }

    /**
     * 取消授权
     *
     * @param sysUserRoleBo 用户角色关联信息
     * @return 操作结果
     */
    @Override
    public Boolean removeAuthUser(SysUserRoleBo sysUserRoleBo) {
        QueryWrapper query = query()
            .eq(SysUserRole::getRoleId, sysUserRoleBo.getRoleId(), ObjectUtil.isNotNull(sysUserRoleBo.getUserId()))
            .eq(SysUserRole::getUserId, sysUserRoleBo.getUserId(), ObjectUtil.isNotNull(sysUserRoleBo.getRoleId()));
        if (SqlUtil.toBool(sysUserRoleMapper.deleteByQuery(query))) {
            cleanOnlineUserByRoleId(sysUserRoleBo.getRoleId());
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 批量取消授权
     *
     * @param roleId  角色ID
     * @param userIds 用户ID
     * @return 操作结果
     */
    @Override
    public Boolean removeAuthUsers(Long roleId, Long[] userIds) {
        List<Long> ids = Arrays.asList(userIds);
        QueryWrapper query = query()
            .eq(SysUserRole::getRoleId, roleId, ObjectUtil.isNotNull(roleId))
            .in(SysUserRole::getUserId, ids, CollUtil.isNotEmpty(ids));
        if (SqlUtil.toBool(sysUserRoleMapper.deleteByQuery(query))) {
            cleanOnlineUserByRoleId(roleId);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 清除在线用户
     *
     * @param roleId 角色ID
     */
    @Override
    public void cleanOnlineUserByRoleId(Long roleId) {
        long userNum = sysUserRoleMapper.selectCountByQuery(query().eq(SysUserRole::getRoleId, roleId));
        if (userNum == 0) {
            return;
        }
        // 根据条件查询缓存中所有的 token
        List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
        if (CollUtil.isEmpty(keys)) {
            return;
        }
        // 角色关联的在线用户
        keys.parallelStream().forEach(key -> {
            String token = StringUtils.substringAfterLast(key, ":");
            // 如果已经过期则跳过
            if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
                return;
            }
            LoginUser loginUser = LoginHelper.getLoginUser(token);
            if (ObjectUtil.isNull(loginUser)) {
                return;
            }
            if (loginUser.getRoles().stream().allMatch(r -> r.getRoleId().equals(roleId))) {
                try {
                    StpUtil.logoutByTokenValue(token);
                } catch (NotLoginException ignored) {
                }
            }
        });
    }

    /**
     * 批量选择用户
     *
     * @param roleId  角色ID
     * @param userIds 用户ID
     * @return 操作结果
     */
    @Override
    public int insertAuthUsers(Long roleId, Long[] userIds) {
        List<SysUserRole> sysUserRoles = StreamUtils.toList(List.of(userIds), userId -> new SysUserRole(userId, roleId));
        cleanOnlineUserByRoleId(roleId);
        int rows = 1;
        if (CollUtil.isNotEmpty(sysUserRoles)) {
            rows = sysUserRoleMapper.insertBatch(sysUserRoles);
        }
        if (rows > 0) {
            cleanOnlineUserByRoleId(roleId);
        }
        return rows;
    }

    /**
     * 修改角色数据权限
     *
     * @param sysRoleBo 角色信息
     * @return 操作结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean authDataScope(SysRoleBo sysRoleBo) {
        SysRole sysRole = MapstructUtils.convert(sysRoleBo, SysRole.class);
        if (ObjectUtil.isNull(sysRole)) {
            return Boolean.FALSE;
        }
        updateById(sysRole);
        sysRoleDeptMapper.deleteByQuery(query().eq(SysRoleDept::getRoleId, sysRole.getRoleId()));
        return insertRoleDept(sysRoleBo);
    }

    /**
     * 新增角色与部门关联
     *
     * @param sysRoleBo 角色信息
     * @return 操作结果
     */
    private Boolean insertRoleDept(SysRoleBo sysRoleBo) {
        List<SysRoleDept> sysRoleDepts = new ArrayList<>();
        for (Long deptId : sysRoleBo.getDeptIds()) {
            SysRoleDept sysRoleDept = new SysRoleDept(sysRoleBo.getRoleId(), deptId);
            sysRoleDepts.add(sysRoleDept);
        }
        if (CollUtil.isNotEmpty(sysRoleDepts)) {
            return SqlUtil.toBool(sysRoleDeptMapper.insertBatch(sysRoleDepts));
        }
        return Boolean.TRUE;
    }

    /**
     * 根据用户ID查询角色
     *
     * @param userId 用户ID
     * @return 查询结果
     */
    @Override
    public List<SysRoleVo> selectRolesByUserId(Long userId) {
        return queryChain().select(
                SysRoleTableDef.SYS_ROLE.ROLE_ID,
                SysRoleTableDef.SYS_ROLE.ROLE_NAME,
                SysRoleTableDef.SYS_ROLE.ROLE_KEY,
                SysRoleTableDef.SYS_ROLE.ROLE_SORT,
                SysRoleTableDef.SYS_ROLE.DATA_SCOPE,
                SysRoleTableDef.SYS_ROLE.ROLE_STATUS)
            .from(SysRole.class)
            .where(SysRoleTableDef.SYS_ROLE.ROLE_ID.in(
                query().select(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID)
                    .from(SysUserRole.class)
                    .where(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID.eq(userId))))
            .listAs(SysRoleVo.class);
    }

    /**
     * 根据用户ID查询角色列表(包含授权)
     *
     * @param userId 用户ID
     * @return 查询结果
     */
    @Override
    public List<SysRoleVo> selectRolesAuthByUserId(Long userId) {
        QueryWrapper query = query().select(QueryMethods.distinct(SYS_ROLE.DEFAULT_COLUMNS))
            .from(SysRole.class)
            .leftJoin(SysUserRole.class)
            .on(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID.eq(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID))
            .leftJoin(SysUser.class)
            .on(SysUserTableDef.SYS_USER.USER_ID.eq(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID))
            .leftJoin(SysDept.class)
            .on(SysDeptTableDef.SYS_DEPT.DEPT_ID.eq(SysUserTableDef.SYS_USER.DEPT_ID))
            .where(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID.eq(userId));
        List<SysRoleVo> sysRoleVos = listAs(query, SysRoleVo.class);
        List<SysRoleVo> roleVos = selectRoleAll();
        Set<Long> roleIds = StreamUtils.toSet(sysRoleVos, SysRoleVo::getRoleId);
        for (SysRoleVo roleVo : roleVos) {
            if (roleIds.contains(roleVo.getRoleId())) {
                roleVo.setFlag(true);
            }
        }
        return roleVos;
    }


    /**
     * 根据用户ID查询角色权限
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    @Override
    public Set<String> selectRolePermissionByUserId(Long userId) {
        List<SysRoleVo> perms = queryChain()
            .select(QueryMethods.distinct(SYS_ROLE.DEFAULT_COLUMNS))
            .from(SysRole.class)
            .leftJoin(SysUserRole.class)
            .on(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID.eq(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID))
            .leftJoin(SysUser.class)
            .on(SysUserTableDef.SYS_USER.USER_ID.eq(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID))
            .leftJoin(SysDept.class)
            .on(SysDeptTableDef.SYS_DEPT.DEPT_ID.eq(SysUserTableDef.SYS_USER.DEPT_ID))
            .where(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID.eq(userId))
            .listAs(SysRoleVo.class);
        Set<String> permsSet = new HashSet<>();
        for (SysRoleVo perm : perms) {
            if (ObjectUtil.isNotNull(perm)) {
                permsSet.addAll(StringUtils.splitList(perm.getRoleKey().trim()));
            }
        }
        return permsSet;
    }

    /**
     * 根据用户ID查询角色列表
     *
     * @param userId 用户ID
     * @return 查询结果
     */
    @Override
    public List<Long> selectRoleListByUserId(Long userId) {
        return StreamUtils.toList(selectRolesByUserId(userId), SysRoleVo::getRoleId);
    }

    /**
     * 根据条件查询角色信息
     *
     * @param sysRoleBo 角色信息
     * @return 角色数据集合
     */
    @Override
    public List<SysRoleVo> selectRoleList(SysRoleBo sysRoleBo) {
        QueryWrapper query = DataScopeUtils.addCondition(builderQueryWrapper(sysRoleBo));
        query.select(QueryMethods.distinct(SYS_ROLE.DEFAULT_COLUMNS))
            .from(SysRole.class)
            .leftJoin(SysUserRole.class)
            .on(SysUserRoleTableDef.SYS_USER_ROLE.ROLE_ID.eq(SYS_ROLE.ROLE_ID))
            .leftJoin(SysUser.class)
            .on(SysUserTableDef.SYS_USER.USER_ID.eq(SysUserRoleTableDef.SYS_USER_ROLE.USER_ID))
            .leftJoin(SysDept.class)
            .on(SysDeptTableDef.SYS_DEPT.DEPT_ID.eq(SysUserTableDef.SYS_USER.DEPT_ID));
        return listAs(query, SysRoleVo.class);
    }

    /**
     * 查询所有角色列表
     *
     * @return 角色列表
     */
    @Override
    public List<SysRoleVo> selectRoleAll() {
        return this.selectRoleList(new SysRoleBo());
    }
}
